package org.itstack.demo.netty.multicast.server;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.InternetProtocolFamily;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.CharsetUtil;
import io.netty.util.NetUtil;

/**
 * UDP组播 Server
 * @author yuxuan
 *
 */
public class Mserver {


	public static void main(String[] args) {
		System.setProperty("java.net.preferIPv4Stack", "true");//只使用IPV4
		// 组播地址
		InetSocketAddress groupAddress = new InetSocketAddress("224.2.1.1", 9000);
		InetSocketAddress groupAddress02 = new InetSocketAddress("224.2.1.100", 9010);

		EventLoopGroup group = new NioEventLoopGroup();
		try {
			NetworkInterface ni = NetUtil.LOOPBACK_IF;
			Enumeration<InetAddress> addresses = ni.getInetAddresses();
			InetAddress localAddress = null;
			while (addresses.hasMoreElements()) {
				InetAddress address = addresses.nextElement();
				if (address instanceof Inet4Address){
					localAddress = address;
				}
			}
			System.out.println(localAddress);
			Bootstrap bootstrap = new Bootstrap();
			//设置NioDatagramChannel
			bootstrap.group(group).channelFactory(new ChannelFactory<NioDatagramChannel>() {
				@Override
				public NioDatagramChannel newChannel() {
					// 指定协议簇为 IPv4
					return new NioDatagramChannel(InternetProtocolFamily.IPv4);
				}
			})
			// .channel(NioDatagramChannel.class)
			// .localAddress(localAddress,groupAddress.getPort())
			//设置Option 组播
            .option(ChannelOption.IP_MULTICAST_IF, ni)
            //设置Option 地址
            .option(ChannelOption.IP_MULTICAST_ADDR, localAddress)
            //设置地址
            .option(ChannelOption.SO_REUSEADDR, true)
			.handler(new ChannelInitializer<NioDatagramChannel>() {
				@Override
				public void initChannel(NioDatagramChannel ch) throws Exception {
					ChannelPipeline addLast = ch.pipeline().addLast();
					addLast.addLast(new SimpleChannelInboundHandler<DatagramPacket>() {//接收信息处理

						@Override
						protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
							// 打印一句话
							System.out.println(msg.sender()+" >>> "+ msg.content().toString(CharsetUtil.UTF_8));
						}
					});
				}
			});

			//获取NioDatagramChannel
			// NioDatagramChannel channel = (NioDatagramChannel) bootstrap.bind().sync().channel();
			NioDatagramChannel channel = (NioDatagramChannel) bootstrap.bind(groupAddress.getPort()).sync().channel();
			NioDatagramChannel channel02 = (NioDatagramChannel) bootstrap.bind(groupAddress02.getPort()).sync().channel();
			//加入组
			channel.joinGroup(groupAddress, ni).sync();
			// channel02.joinGroup(groupAddress, ni).sync();
			// channel.joinGroup(groupAddress02, ni).sync();
			channel02.joinGroup(groupAddress02, ni).sync();
			//关闭Channel
			channel.closeFuture().await();
			channel02.closeFuture().await();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			group.shutdownGracefully();//优雅退出
		}
	}
}
